package ireflect

import (
	"github.com/google/go-cmp/cmp"
	"reflect"
)

// IsNil 判断指针 & 泛型非空
func IsNil(i interface{}) bool {
	vi := reflect.ValueOf(i)
	if vi.Kind() == reflect.Ptr {
		return vi.IsNil()
	}
	return false
}

// GetType 获取参数类型
func GetType(i any) reflect.Type {
	return reflect.TypeOf(i)
}

// GetFields 获取结构体字段
func GetFields(i struct{}) []reflect.StructField {
	retH := reflect.TypeOf(i)
	count := retH.NumField()
	var slice = make([]reflect.StructField, 0, count)
	for i := 0; i < retH.NumField(); i++ {
		slice = append(slice, retH.Field(i))
	}
	return slice
}

// FindFrom 过滤: 寻找和目标值匹配的数据
func FindFrom[T interface{}, R interface{}](arrays []T, fn func(t T) R, expectedValue R) []T {
	result := make([]T, 0)
	for i := 0; i < len(arrays); i++ {
		fnValue := fn(arrays[i])
		matched := cmp.Equal(fnValue, expectedValue)
		if matched {
			result = append(result, arrays[i])
		}
	}
	return result
}

// Map 映射: 将数组映射为子属性的数组
func Map[T interface{}, R interface{}](arrays []T, fn func(T) R) []R {
	result := make([]R, 0)
	for i := 0; i < len(arrays); i++ {
		fnValue := fn(arrays[i])
		result = append(result, fnValue)
	}
	return result
}
